from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, or_
from app.db.postgres import get_session
from app.models import EvaluationReportHeader, EvaluationReport
from app.schemas.report import ReportHeaderCreate, ReportHeaderUpdate, ReportHeaderRead


router = APIRouter(prefix="/report-headers", tags=["report-headers"])


@router.get("")
async def list_headers(
    q: str | None = Query(None),
    page: int = Query(1, ge=1),
    page_size: int = Query(10, ge=1, le=200),
    session: AsyncSession = Depends(get_session),
):
    stmt = select(EvaluationReportHeader)
    count_stmt = select(func.count()).select_from(EvaluationReportHeader)
    if q:
        like = f"%{q}%"
        stmt = stmt.where(or_(EvaluationReportHeader.code.ilike(like), EvaluationReportHeader.name.ilike(like)))
        count_stmt = count_stmt.where(or_(EvaluationReportHeader.code.ilike(like), EvaluationReportHeader.name.ilike(like)))
    total_res = await session.execute(count_stmt)
    total = total_res.scalar() or 0
    res = await session.execute(
        stmt.order_by(EvaluationReportHeader.created_at.desc())
            .offset((page - 1) * page_size)
            .limit(page_size)
    )
    items = [ReportHeaderRead.model_validate(x) for x in res.scalars().all()]
    return {"items": items, "total": total}


@router.post("", response_model=ReportHeaderRead)
async def create_header(payload: ReportHeaderCreate, session: AsyncSession = Depends(get_session)):
    exists = await session.execute(select(func.count()).select_from(EvaluationReportHeader).where(EvaluationReportHeader.code == payload.code))
    if exists.scalar():
        raise HTTPException(status_code=400, detail="code_exists")
    obj = EvaluationReportHeader(code=payload.code, name=payload.name)
    session.add(obj)
    await session.flush()
    await session.refresh(obj)
    await session.commit()
    return ReportHeaderRead.model_validate(obj)


@router.put("/{header_id}", response_model=ReportHeaderRead)
async def update_header(header_id: str, payload: ReportHeaderUpdate, session: AsyncSession = Depends(get_session)):
    obj = await session.get(EvaluationReportHeader, header_id)
    if not obj:
        raise HTTPException(status_code=404, detail="header_not_found")
    obj.name = payload.name
    await session.flush()
    await session.refresh(obj)
    await session.commit()
    return ReportHeaderRead.model_validate(obj)


@router.delete("/{header_id}")
async def delete_header(header_id: str, session: AsyncSession = Depends(get_session)):
    obj = await session.get(EvaluationReportHeader, header_id)
    if not obj:
        raise HTTPException(status_code=404, detail="header_not_found")
    cnt = await session.execute(select(func.count()).select_from(EvaluationReport).where(EvaluationReport.report_id == obj.id))
    if cnt.scalar():
        raise HTTPException(status_code=400, detail="versions_exist")
    await session.delete(obj)
    await session.commit()
    return {"ok": True}
